﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////

#include "ExprParser.h"

#include <math.h>

#include "UnitHelper.h"
#include "GbmpNew.h"
#include "TransferOwnership.h"

#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

using namespace std;
using namespace gcmp;

ExprCustomParser::ExprCustomParser(IExprEngine* aEngine)
    : m_scanner(aEngine)
    , m_opRootNode(nullptr)
    , m_pEngine(aEngine)
    , m_isNull(true)
    , m_isValid(true)
    , m_currentToken(ExprTokenType::EndInput)
    , m_errorPos(0)
    , m_errorType(EnErrorType::Undefine)
{
    m_strExpression.clear();
}

ExprCustomParser::~ExprCustomParser()
{
}

const ExprNode* ExprCustomParser::GetRootNode() const
{
    return m_opRootNode.get();
}

wchar_t* ExprCustomParser::SetExpression(const wchar_t* aValue)
{
    m_isValid = true;
    int length = static_cast<int>(wcslen(aValue));
    if (length > 0)
    {
        m_strExpression.clear();
        m_strExpression.resize(length + 1);
        wcscpy(&m_strExpression[0], aValue);
        // 设置词法分析器
        m_scanner.SetInputString(&m_strExpression[0]);
        m_currentToken = m_scanner.GetToken();
        m_isNull = false;
        m_opRootNode = Expr();
        if (m_currentToken != ExprTokenType::EndInput)
        {
            // 表达式未被完整解析
            ParseError(EnErrorType::RedundantRParen);
        }
    }
    else
        m_isNull = true;

    return &m_strExpression[0];
}

ExprDataType ExprCustomParser::ResultType() const
{
    if (m_opRootNode)
        return m_opRootNode->GetDataType();
    else
        return ExprDataType::Unknown;
}

UnitMap ExprCustomParser::ResultUnitType()
{
    if (m_opRootNode)
        return m_opRootNode->GetUnitType();
    else
        return UnitMap(ExprUnitType::Invalid);
}

ExprNodeData* ExprCustomParser::Result()
{
    if (m_opRootNode)
        return m_opRootNode->GetData();
    else
        return nullptr;
}

bool ExprCustomParser::GetIsNull() const
{
    return m_isNull;
}

bool ExprCustomParser::GetIsValid() const
{
    return m_isValid;
}

void ExprCustomParser::EvaluateNode(ExprNode* node, IExprNodeDataProvider* aDataProvider)
{
    if (!node)
        return;
    if (!m_isValid)
        return;
    ExprNode* left, * right;
    left = (dynamic_cast<ExprCustumNode*>(node))->m_opLeftChild.get();
    right = (dynamic_cast<ExprCustumNode*>(node))->m_opRightChild.get();
    ExprType nodeType = node->GetNodeType();

    if (nodeType == ExprType::Const) // 对于常数,不用计算
    {
        EvaluateConstNode(node);
    }
    else if (nodeType == ExprType::ID)
    {
        EvaluateIDNode(node, aDataProvider);
    }
    else if (nodeType == ExprType::UnaryOperate) // 一元操作符
    {
        EvaluateUnaryOperateNode(left, aDataProvider, node);
    }
    else if (nodeType == ExprType::BinaryOperate) // 二元操作符
    {
        EvaluateBinaryOperateNode(left, right, node, aDataProvider);
    }
    else if (nodeType == ExprType::Function) // 自定义函数
    {
        EvaluateFunctionNode(node, aDataProvider);
    }
    else if (nodeType == ExprType::Expr) // 嵌套的表达式
    {
        EvaluateNestingExprNode(node, aDataProvider);
    }
    else
    {
        ParseError(EnErrorType::Undefine);
    }
}

void ExprCustomParser::EvaluateNestingExprNode(ExprNode* node, IExprNodeDataProvider* aDataProvider)
{
    ExprIDNode* pExprNode = dynamic_cast<ExprIDNode*> (node);
    if (pExprNode == nullptr)
    {
        ParseError(EnErrorType::Undefine);
        return;
    }

    // 嵌套调用表达式解析
    IExprParser* pCallPaser = m_pEngine->FindParser(pExprNode->GetNodeCode());
    if (pCallPaser != nullptr)
    {
        pCallPaser->Evaluate();
        ExprDataType callReturnType = pCallPaser->ResultType();
        // 处理数值单位
        UnitMap unitType(aDataProvider->GetUnitType(pExprNode->GetNodeCode()));
        pExprNode->m_data.SetUnitType(unitType);
        pExprNode->m_data.SetType(callReturnType);
        switch (callReturnType)
        {
        case ExprDataType::Integer:
        {
            pExprNode->m_data.SetAsInteger(pCallPaser->Result()->GetAsInteger());
            break;
        }
        case ExprDataType::Float:
        {
            double valueFloat = pCallPaser->Result()->GetAsFloat();
            if (unitType.GetSingleUnit() == ExprUnitType::Int)
            {
                valueFloat = static_cast<int>(pCallPaser->Result()->GetAsFloat() + 0.5);
                unitType.Clear();
                unitType.InitialFrom(ExprUnitType::Double);
                pExprNode->m_data.SetUnitType(unitType);
            }
            pExprNode->m_data.SetAsFloat(valueFloat);
            break;
        }
        case ExprDataType::Boolean:
        {
            pExprNode->m_data.SetAsBoolean(pCallPaser->Result()->GetAsBoolean());
            break;
        }
        case ExprDataType::String:
        {
            pExprNode->m_data.SetAsString(pCallPaser->Result()->GetAsString());
            break;
        }
        default:
        {
            ParseError(EnErrorType::Undefine);
            return;
        }
        }
    }
    else
    {
        ParseError(EnErrorType::Undefine);
        return;
    }
}

void ExprCustomParser::EvaluateFunctionNode(ExprNode* node, IExprNodeDataProvider* aDataProvider)
{
    ExprFunctionNode* funcnode = dynamic_cast<ExprFunctionNode*>(node);
    // 先计算参数的值
    for (int i = 0; i < funcnode->GetParams()->Count(); i++)
        EvaluateNode(funcnode->GetParamsFW()->GetParamNodeFW(i), aDataProvider);
    // 然后调用函数计算函数值
    IExprCustomFunction* func = m_pEngine->FindFunction(funcnode->GetNodeCode());
    if (func)
    {
        if (func->DoExectute(funcnode->GetParamsFW(), funcnode->GetData(), funcnode->GetTag()))
        {
            funcnode->m_data.SetType(func->GetResultDataType());
        }
        else
        {
            ParseError(EnErrorType::Undefine);
        }
    }
    else
    {
        ParseError(EnErrorType::Undefine);
    }
}

void ExprCustomParser::EvaluateUnaryOperateNode(ExprNode* left, IExprNodeDataProvider* aDataProvider, ExprNode* node)
{
    if (!left)
    {
        ParseError(EnErrorType::Undefine);
        return;
    }
    EvaluateNode(left, aDataProvider);
    ExprCustumNode* unarynode = dynamic_cast<ExprCustumNode*>(node);
    ExprTokenType token = unarynode->m_token;
    switch (token)
    {
    case ExprTokenType::Minus:
        // 负号
        unarynode->m_data.SetUnitType(left->GetUnitType());

        if (left->GetDataType() == ExprDataType::Integer || left->GetDataType() == ExprDataType::Float)
        {
            unarynode->m_data.SetType(left->GetDataType());
            if (left->GetDataType() == ExprDataType::Integer)
                unarynode->m_data.SetAsInteger(-1 * left->GetData()->GetAsInteger());
            else
                unarynode->m_data.SetAsFloat(-1 * left->GetData()->GetAsFloat());
        }
        break;
    case ExprTokenType::Not:
        if (left->GetDataType() == ExprDataType::Boolean)
        {
            unarynode->m_data.SetType(ExprDataType::Boolean);
            unarynode->m_data.SetAsBoolean(!left->GetData()->GetAsBoolean());
        }
        break;
    default:
        ParseError(EnErrorType::Undefine);
    }
}

void ExprCustomParser::EvaluateIDNode(ExprNode* node, IExprNodeDataProvider* aDataProvider)
{
    ExprIDNode* idnode = dynamic_cast<ExprIDNode*>(node);
    if (aDataProvider)
    {
        ExprDataType resultDataType = aDataProvider->GetResultDataType(idnode->GetNodeCode());
        if (resultDataType == ExprDataType::Unknown)
        {
            ParseError(EnErrorType::Undefine);
            return;
        }
        ExprUnitType unitType = aDataProvider->GetUnitType(idnode->GetNodeCode());

        UnitMap types(unitType);
        idnode->m_data.SetUnitType(types);
        idnode->m_data.SetType(resultDataType);
        aDataProvider->SetExprData(idnode->GetNodeCode(), idnode->GetData(), idnode->GetTag());
    }
    else
    {
        ParseError(EnErrorType::Undefine);
        return;
    }
}

inline void ExprCustomParser::EvaluateConstNode(ExprNode* node)
{
    if (node->GetData() != nullptr)
    {
        ExprDataType dataType = node->GetDataType();
        if (dataType == ExprDataType::Boolean)
        {
            UnitMap types(ExprUnitType::Bool);
            node->GetData()->SetUnitType(types);
        }
        else if (dataType == ExprDataType::String)
        {
            UnitMap types(ExprUnitType::String);
            node->GetData()->SetUnitType(types);
        }
        else
        {
            UnitMap types(ExprUnitType::Num);
            node->GetData()->SetUnitType(types);
        }
    }
}

void ExprCustomParser::EvaluateBinaryOperateNode(ExprNode* left, ExprNode* right, ExprNode* node, IExprNodeDataProvider* aDataProvider)
{
    if (left == nullptr || right == nullptr)
    {
        ParseError(EnErrorType::Undefine);
        return;
    }
    ExprCustumNode* binarynode = dynamic_cast<ExprCustumNode*>(node);
    ExprTokenType token = binarynode->m_token;
    if (token == ExprTokenType::And || token == ExprTokenType::Or) // 支持断点表达式
        EvaluateNode(left, aDataProvider);
    else
    {
        EvaluateNode(left, aDataProvider);
        EvaluateNode(right, aDataProvider);
    }
    UnitMap result;
    switch (token)
    {
    case ExprTokenType::Plus:
        EvaluatePlusOperateNode(left, right, result, binarynode);
        break;
    case ExprTokenType::Minus:
        EvaluateMinusOperateNode(left, right, result, binarynode);
        break;
    case ExprTokenType::Times:
        EvaluateMultiplyOperateNode(left, right, result, binarynode);
        break;
    case ExprTokenType::Over:
        EvaluateDivideOperateNode(left, right, result, binarynode);
        break;
    case ExprTokenType::Modulus:
        EvaluateModulusOperateNode(left, right, result, binarynode);
        break;
    case ExprTokenType::EQ:
        EvaluateEqualOperateNode(left, right, result, binarynode);
        break;
    case ExprTokenType::LT:
        EvaluateLessOperateNode(left, right, result, binarynode);
        break;
    case ExprTokenType::LE:
        EvaluateLessEqualOperateNode(left, right, result, binarynode);
        break;
    case ExprTokenType::GT:
        EvaluateGreaterOperateNode(left, right, result, binarynode);
        break;
    case ExprTokenType::GE:
        EvaluateGreaterEqualOperateNode(left, right, result, binarynode);
        break;
    case ExprTokenType::NotEQ:
        EvaluateNotEqualOperateNode(left, right, result, binarynode);
        break;
    case ExprTokenType::And:
        EvaluateAndOperateNode(left, binarynode, right, aDataProvider);
        break;
    case ExprTokenType::Or:
        EvaluateOrOperateNode(left, binarynode, right, aDataProvider);
        break;
    default:
        ParseError(EnErrorType::Undefine);
    }
}

void ExprCustomParser::EvaluateOrOperateNode(ExprNode* left, ExprCustumNode* binarynode, ExprNode* right, IExprNodeDataProvider* aDataProvider)
{
    if (left->GetDataType() == ExprDataType::Boolean)
    {
        if (left->GetData()->GetAsBoolean() == true) // 支持断点表达式
        {
            binarynode->m_data.SetType(ExprDataType::Boolean);
            binarynode->m_data.SetAsBoolean(true);
        }
        else
        {
            EvaluateNode(right, aDataProvider);
            if (right->GetDataType() == ExprDataType::Boolean)
            {
                binarynode->m_data.SetType(ExprDataType::Boolean);
                binarynode->m_data.SetAsBoolean(right->GetData()->GetAsBoolean());
            }
            else
                ParseError(EnErrorType::Undefine);
        }
    }
    else
        ParseError(EnErrorType::Undefine);
}

void ExprCustomParser::EvaluateAndOperateNode(ExprNode* left, ExprCustumNode* binarynode, ExprNode* right, IExprNodeDataProvider* aDataProvider)
{
    if (left->GetDataType() == ExprDataType::Boolean)
    {
        if (left->GetData()->GetAsBoolean() == false) // 支持断点表达式
        {
            binarynode->m_data.SetType(ExprDataType::Boolean);
            binarynode->m_data.SetAsBoolean(false);
        }
        else
        {
            EvaluateNode(right, aDataProvider);
            if (right->GetDataType() == ExprDataType::Boolean)
            {
                binarynode->m_data.SetType(ExprDataType::Boolean);
                binarynode->m_data.SetAsBoolean(right->GetData()->GetAsBoolean());
            }
            else
                ParseError(EnErrorType::Undefine);
        }
    }
    else
        ParseError(EnErrorType::Undefine);
}

void ExprCustomParser::EvaluateNotEqualOperateNode(ExprNode* left, ExprNode* right, UnitMap& result, ExprCustumNode* binarynode)
{
    // 单位运算
    if (UnitHelper::CheckUnitCompare(left->GetUnitType(), right->GetUnitType(), result))
    {
        binarynode->m_data.SetUnitType(result);
    }
    else
    {
        ParseError(EnErrorType::UnitInvalid);
        return;
    }
    // 数值运算
    if (left->GetDataType() == ExprDataType::Integer && right->GetDataType() == ExprDataType::Integer)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsInteger() != right->GetData()->GetAsInteger());
    }
    else if (left->GetDataType() == ExprDataType::Integer && right->GetDataType() == ExprDataType::Float)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsInteger() != right->GetData()->GetAsFloat());
    }
    else if (left->GetDataType() == ExprDataType::Float && right->GetDataType() == ExprDataType::Integer)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsFloat() != right->GetData()->GetAsInteger());
    }
    else if (left->GetDataType() == ExprDataType::Float && right->GetDataType() == ExprDataType::Float)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsFloat() != right->GetData()->GetAsFloat());
    }
    else if (left->GetDataType() == ExprDataType::Boolean && right->GetDataType() == ExprDataType::Boolean)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsBoolean() != right->GetData()->GetAsBoolean());
    }
    else
        ParseError(EnErrorType::Undefine);
}

void ExprCustomParser::EvaluateGreaterEqualOperateNode(ExprNode* left, ExprNode* right, UnitMap& result, ExprCustumNode* binarynode)
{
    // 单位运算
    if (UnitHelper::CheckUnitCompare(left->GetUnitType(), right->GetUnitType(), result))
    {
        binarynode->m_data.SetUnitType(result);
    }
    else
    {
        ParseError(EnErrorType::UnitInvalid);
        return;
    }
    // 数值运算
    if (left->GetDataType() == ExprDataType::Integer && right->GetDataType() == ExprDataType::Integer)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsInteger() >= right->GetData()->GetAsInteger());
    }
    else if (left->GetDataType() == ExprDataType::Integer && right->GetDataType() == ExprDataType::Float)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsInteger() >= right->GetData()->GetAsFloat());
    }
    else if (left->GetDataType() == ExprDataType::Float && right->GetDataType() == ExprDataType::Integer)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsFloat() >= right->GetData()->GetAsInteger());
    }
    else if (left->GetDataType() == ExprDataType::Float && right->GetDataType() == ExprDataType::Float)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsFloat() >= right->GetData()->GetAsFloat());
    }
    else
        ParseError(EnErrorType::Undefine);
}

void ExprCustomParser::EvaluateGreaterOperateNode(ExprNode* left, ExprNode* right, UnitMap& result, ExprCustumNode* binarynode)
{
    // 单位运算
    if (UnitHelper::CheckUnitCompare(left->GetUnitType(), right->GetUnitType(), result))
    {
        binarynode->m_data.SetUnitType(result);
    }
    else
    {
        ParseError(EnErrorType::UnitInvalid);
        return;
    }
    // 数值运算
    if (left->GetDataType() == ExprDataType::Integer && right->GetDataType() == ExprDataType::Integer)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsInteger() > right->GetData()->GetAsInteger());
    }
    else if (left->GetDataType() == ExprDataType::Integer && right->GetDataType() == ExprDataType::Float)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsInteger() > right->GetData()->GetAsFloat());
    }
    else if (left->GetDataType() == ExprDataType::Float && right->GetDataType() == ExprDataType::Integer)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsFloat() > right->GetData()->GetAsInteger());
    }
    else if (left->GetDataType() == ExprDataType::Float && right->GetDataType() == ExprDataType::Float)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsFloat() > right->GetData()->GetAsFloat());
    }
    else
        ParseError(EnErrorType::Undefine);
}

void ExprCustomParser::EvaluateLessEqualOperateNode(ExprNode* left, ExprNode* right, UnitMap& result, ExprCustumNode* binarynode)
{
    // 单位运算
    if (UnitHelper::CheckUnitCompare(left->GetUnitType(), right->GetUnitType(), result))
    {
        binarynode->m_data.SetUnitType(result);
    }
    else
    {
        ParseError(EnErrorType::UnitInvalid);
        return;
    }
    // 数值运算
    if (left->GetDataType() == ExprDataType::Integer && right->GetDataType() == ExprDataType::Integer)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsInteger() <= right->GetData()->GetAsInteger());
    }
    else if (left->GetDataType() == ExprDataType::Integer && right->GetDataType() == ExprDataType::Float)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsInteger() <= right->GetData()->GetAsFloat());
    }
    else if (left->GetDataType() == ExprDataType::Float && right->GetDataType() == ExprDataType::Integer)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsFloat() <= right->GetData()->GetAsInteger());
    }
    else if (left->GetDataType() == ExprDataType::Float && right->GetDataType() == ExprDataType::Float)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsFloat() <= right->GetData()->GetAsFloat());
    }
    else
        ParseError(EnErrorType::Undefine);
}

void ExprCustomParser::EvaluateLessOperateNode(ExprNode* left, ExprNode* right, UnitMap& result, ExprCustumNode* binarynode)
{
    // 单位运算
    if (UnitHelper::CheckUnitCompare(left->GetUnitType(), right->GetUnitType(), result))
    {
        binarynode->m_data.SetUnitType(result);
    }
    else
    {
        ParseError(EnErrorType::UnitInvalid);
        return;
    }
    // 数值运算
    if (left->GetDataType() == ExprDataType::Integer && right->GetDataType() == ExprDataType::Integer)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsInteger() < right->GetData()->GetAsInteger());
    }
    else if (left->GetDataType() == ExprDataType::Integer && right->GetDataType() == ExprDataType::Float)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsInteger() < right->GetData()->GetAsFloat());
    }
    else if (left->GetDataType() == ExprDataType::Float && right->GetDataType() == ExprDataType::Integer)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsFloat() < right->GetData()->GetAsInteger());
    }
    else if (left->GetDataType() == ExprDataType::Float && right->GetDataType() == ExprDataType::Float)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsFloat() < right->GetData()->GetAsFloat());
    }
    else
        ParseError(EnErrorType::Undefine);
}

void ExprCustomParser::EvaluateEqualOperateNode(ExprNode* left, ExprNode* right, UnitMap& result, ExprCustumNode* binarynode)
{
    // 单位运算
    if (UnitHelper::CheckUnitCompare(left->GetUnitType(), right->GetUnitType(), result))
    {
        binarynode->m_data.SetUnitType(result);
    }
    else
    {
        ParseError(EnErrorType::UnitInvalid);
        return;
    }
    // 数值运算
    if (left->GetDataType() == ExprDataType::Integer && right->GetDataType() == ExprDataType::Integer)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsInteger() == right->GetData()->GetAsInteger());
    }
    else if (left->GetDataType() == ExprDataType::Integer && right->GetDataType() == ExprDataType::Float)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsInteger() == right->GetData()->GetAsFloat());
    }
    else if (left->GetDataType() == ExprDataType::Float && right->GetDataType() == ExprDataType::Integer)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsFloat() == right->GetData()->GetAsInteger());
    }
    else if (left->GetDataType() == ExprDataType::Float && right->GetDataType() == ExprDataType::Float)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsFloat() == right->GetData()->GetAsFloat());
    }
    else if (left->GetDataType() == ExprDataType::Boolean && right->GetDataType() == ExprDataType::Boolean)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        binarynode->m_data.SetAsBoolean(left->GetData()->GetAsBoolean() == right->GetData()->GetAsBoolean());
    }
    else if (left->GetDataType() == ExprDataType::String && right->GetDataType() == ExprDataType::String)
    {
        binarynode->m_data.SetType(ExprDataType::Boolean);
        // case-sensitive comparison
        binarynode->m_data.SetAsBoolean(wcscmp(left->GetData()->GetAsString(), right->GetData()->GetAsString()) == 0);
    }
    else
        ParseError(EnErrorType::Undefine);
}

void ExprCustomParser::EvaluateModulusOperateNode(ExprNode* left, ExprNode* right, UnitMap& result, ExprCustumNode* binarynode)
{
    // 单位运算%
    if (UnitHelper::CheckUnitModulus(left->GetUnitType(), right->GetUnitType(), result))
    {
        binarynode->m_data.SetUnitType(result);
    }
    else
    {
        ParseError(EnErrorType::UnitInvalid);
        return;
    }
    // 数值运算
    if ((left->GetDataType() == ExprDataType::Integer || left->GetDataType() == ExprDataType::Float)
        && (right->GetDataType() == ExprDataType::Integer || right->GetDataType() == ExprDataType::Float))
    {
        int leftIntValue = left->GetData()->GetAsInteger();
        if (left->GetDataType() == ExprDataType::Float)
        {
            double value = left->GetData()->GetAsFloat();
            leftIntValue = static_cast<int>(value);
            if (abs(value - leftIntValue) > PRECISION_DEF)
            {
                ParseError(EnErrorType::Undefine);
                return;
            }
        }
        int rightIntValue = right->GetData()->GetAsInteger();
        if (right->GetDataType() == ExprDataType::Float)
        {
            double value = right->GetData()->GetAsFloat();
            rightIntValue = static_cast<int>(value);
            if (abs(value - rightIntValue) > PRECISION_DEF)
            {
                ParseError(EnErrorType::Undefine);
                return;
            }
        }
        if (rightIntValue == 0)
        {
            ParseError(EnErrorType::DivisorIsZero);
            return;
        }
        else
        {
            binarynode->m_data.SetType(ExprDataType::Integer);
            binarynode->m_data.SetAsInteger(leftIntValue % rightIntValue);
        }
    }
    else
        ParseError(EnErrorType::Undefine);
}

void ExprCustomParser::EvaluateDivideOperateNode(ExprNode* left, ExprNode* right, UnitMap& result, ExprCustumNode* binarynode)
{
    // 包含中文括号无效
    std::wstring leftStr;
    std::wstring rightStr;
    ExprIDNode* pLeft = dynamic_cast<ExprIDNode*>(left);
    ExprIDNode* pRight = dynamic_cast<ExprIDNode*>(right);
    if (pLeft)
    {
        leftStr = pLeft->GetNodeCode();
    }
    if (pRight)
    {
        rightStr = pRight->GetNodeCode();
    }

    if (pLeft && pLeft->GetNodeType() != ExprType::ID && pLeft->GetNodeType() != ExprType::Expr && (leftStr.find(L"）") != std::wstring::npos || leftStr.find(L"（") != std::wstring::npos))
    {
        ParseError(EnErrorType::Undefine);
        return;
    }
    if (pRight && pRight->GetNodeType() != ExprType::ID && pRight->GetNodeType() != ExprType::Expr && (rightStr.find(L"）") != std::wstring::npos || rightStr.find(L"（") != std::wstring::npos))
    {
        ParseError(EnErrorType::Undefine);
        return;
    }
    // 单位运算/
    if (UnitHelper::CheckUnitDivided(left->GetUnitType(), right->GetUnitType(), result))
    {
        binarynode->m_data.SetUnitType(result);
    }
    else
    {
        if (pLeft && pLeft->GetNodeType() == ExprType::ID)
        {
            m_exprNodeName.emplace_back(pLeft->GetNodeCode());
        }
        if (pRight && pRight->GetNodeType() == ExprType::ID)
        {
            m_exprNodeName.emplace_back(pRight->GetNodeCode());
        }
        ParseError(EnErrorType::UnitInvalid);
        return;
    }
    // 数值运算
    if (left->GetDataType() == ExprDataType::Integer && right->GetDataType() == ExprDataType::Integer)
    {
        if (right->GetData()->GetAsInteger() == 0)
        {
            ParseError(EnErrorType::DivisorIsZero);
        }
        else
        {
            binarynode->m_data.SetType(ExprDataType::Float);
            binarynode->m_data.SetAsFloat(1.0 * left->GetData()->GetAsInteger() / right->GetData()->GetAsInteger());
        }
    }
    else if (left->GetDataType() == ExprDataType::Integer && right->GetDataType() == ExprDataType::Float)
    {
        double DOUBLE_EPS = 0.000001;
        if (fabs(right->GetData()->GetAsFloat()) < DOUBLE_EPS)
        {
            ParseError(EnErrorType::DivisorIsZero);
        }
        else
        {
            binarynode->m_data.SetType(ExprDataType::Float);
            binarynode->m_data.SetAsFloat(left->GetData()->GetAsInteger() / right->GetData()->GetAsFloat());
        }
    }
    else if (left->GetDataType() == ExprDataType::Float && right->GetDataType() == ExprDataType::Integer)
    {
        if (right->GetData()->GetAsInteger() == 0)
        {
            ParseError(EnErrorType::DivisorIsZero);
        }
        else
        {
            binarynode->m_data.SetType(ExprDataType::Float);
            binarynode->m_data.SetAsFloat(left->GetData()->GetAsFloat() / right->GetData()->GetAsInteger());
        }
    }
    else if (left->GetDataType() == ExprDataType::Float && right->GetDataType() == ExprDataType::Float)
    {
        double DOUBLE_EPS = 0.000001;
        if (fabs(right->GetData()->GetAsFloat()) < DOUBLE_EPS)
        {
            ParseError(EnErrorType::DivisorIsZero);
        }
        else
        {
            binarynode->m_data.SetType(ExprDataType::Float);
            binarynode->m_data.SetAsFloat(left->GetData()->GetAsFloat() / right->GetData()->GetAsFloat());
        }
    }
    else
        ParseError(EnErrorType::Undefine);
}

void ExprCustomParser::EvaluateMultiplyOperateNode(ExprNode* left, ExprNode* right, UnitMap& result, ExprCustumNode* binarynode)
{
    // 包含中文括号无效
    std::wstring leftStr;
    std::wstring rightStr;
    ExprIDNode* pLeft = dynamic_cast<ExprIDNode*>(left);
    ExprIDNode* pRight = dynamic_cast<ExprIDNode*>(right);
    if (pLeft)
    {
        leftStr = pLeft->GetNodeCode();
    }
    if (pRight)
    {
        rightStr = pRight->GetNodeCode();
    }

    if (pLeft && pLeft->GetNodeType() != ExprType::ID && pLeft->GetNodeType() != ExprType::Expr && (leftStr.find(L"）") != std::wstring::npos || leftStr.find(L"（") != std::wstring::npos))
    {
        ParseError(EnErrorType::Undefine);
        return;
    }
    if (pRight && pRight->GetNodeType() != ExprType::ID && pRight->GetNodeType() != ExprType::Expr && (rightStr.find(L"）") != std::wstring::npos || rightStr.find(L"（") != std::wstring::npos))
    {
        ParseError(EnErrorType::Undefine);
        return;
    }

    // 单位运算*
    if (UnitHelper::CheckUnitMultiply(left->GetUnitType(), right->GetUnitType(), result))
    {
        binarynode->m_data.SetUnitType(result);
    }
    else
    {
        if (pLeft && pLeft->GetNodeType() == ExprType::ID)
        {
            m_exprNodeName.emplace_back(pLeft->GetNodeCode());
        }
        if (pRight && pRight->GetNodeType() == ExprType::ID)
        {
            m_exprNodeName.emplace_back(pRight->GetNodeCode());
        }
        ParseError(EnErrorType::UnitInvalid);
        return;
    }
    // 数值运算
    if (left->GetDataType() == ExprDataType::Integer && right->GetDataType() == ExprDataType::Integer)
    {
        binarynode->m_data.SetType(ExprDataType::Integer);
        binarynode->m_data.SetAsInteger(left->GetData()->GetAsInteger() * right->GetData()->GetAsInteger());
    }
    else if (left->GetDataType() == ExprDataType::Integer && right->GetDataType() == ExprDataType::Float)
    {
        binarynode->m_data.SetType(ExprDataType::Float);
        binarynode->m_data.SetAsFloat(left->GetData()->GetAsInteger() * right->GetData()->GetAsFloat());
    }
    else if (left->GetDataType() == ExprDataType::Float && right->GetDataType() == ExprDataType::Integer)
    {
        binarynode->m_data.SetType(ExprDataType::Float);
        binarynode->m_data.SetAsFloat(left->GetData()->GetAsFloat() * right->GetData()->GetAsInteger());
    }
    else if (left->GetDataType() == ExprDataType::Float && right->GetDataType() == ExprDataType::Float)
    {
        binarynode->m_data.SetType(ExprDataType::Float);
        binarynode->m_data.SetAsFloat(left->GetData()->GetAsFloat() * right->GetData()->GetAsFloat());
    }
    else
        ParseError(EnErrorType::Undefine);
}

void ExprCustomParser::EvaluateMinusOperateNode(ExprNode* left, ExprNode* right, UnitMap& result, ExprCustumNode* binarynode)
{
    // 包含中文括号无效
    std::wstring leftStr;
    std::wstring rightStr;
    ExprIDNode* pLeft = dynamic_cast<ExprIDNode*>(left);
    ExprIDNode* pRight = dynamic_cast<ExprIDNode*>(right);
    if (pLeft)
    {
        leftStr = pLeft->GetNodeCode();
    }
    if (pRight)
    {
        rightStr = pRight->GetNodeCode();
    }

    if (pLeft && pLeft->GetNodeType() != ExprType::ID && pLeft->GetNodeType() != ExprType::Expr && (leftStr.find(L"）") != std::wstring::npos || leftStr.find(L"（") != std::wstring::npos))
    {
        ParseError(EnErrorType::Undefine);
        return;
    }
    if (pRight && pRight->GetNodeType() != ExprType::ID && pRight->GetNodeType() != ExprType::Expr && (rightStr.find(L"）") != std::wstring::npos || rightStr.find(L"（") != std::wstring::npos))
    {
        ParseError(EnErrorType::Undefine);
        return;
    }

    // 单位运算-
    if (UnitHelper::CheckUnitSubtract(left->GetUnitType(), right->GetUnitType(), result))
    {
        binarynode->m_data.SetUnitType(result);
    }
    else
    {
        if (pLeft && pLeft->GetNodeType() == ExprType::ID)
        {
            m_exprNodeName.emplace_back(pLeft->GetNodeCode());
        }
        if (pRight && pRight->GetNodeType() == ExprType::ID)
        {
            m_exprNodeName.emplace_back(pRight->GetNodeCode());
        }
        ParseError(EnErrorType::UnitInvalid);
        return;
    }
    // 数值运算
    if (left->GetDataType() == ExprDataType::Integer && right->GetDataType() == ExprDataType::Integer)
    {
        binarynode->m_data.SetType(ExprDataType::Integer);
        binarynode->m_data.SetAsInteger(left->GetData()->GetAsInteger() - right->GetData()->GetAsInteger());
    }
    else if (left->GetDataType() == ExprDataType::Integer && right->GetDataType() == ExprDataType::Float)
    {
        binarynode->m_data.SetType(ExprDataType::Float);
        binarynode->m_data.SetAsFloat(left->GetData()->GetAsInteger() - right->GetData()->GetAsFloat());
    }
    else if (left->GetDataType() == ExprDataType::Float && right->GetDataType() == ExprDataType::Integer)
    {
        binarynode->m_data.SetType(ExprDataType::Float);
        binarynode->m_data.SetAsFloat(left->GetData()->GetAsFloat() - right->GetData()->GetAsInteger());
    }
    else if (left->GetDataType() == ExprDataType::Float && right->GetDataType() == ExprDataType::Float)
    {
        binarynode->m_data.SetType(ExprDataType::Float);
        binarynode->m_data.SetAsFloat(left->GetData()->GetAsFloat() - right->GetData()->GetAsFloat());
    }
    else
        ParseError(EnErrorType::Undefine);
}

void ExprCustomParser::EvaluatePlusOperateNode(ExprNode* left, ExprNode* right, UnitMap& result, ExprCustumNode* binarynode)
{
    // 包含中文括号无效
    std::wstring leftStr;
    std::wstring rightStr;
    ExprIDNode* pLeft = dynamic_cast<ExprIDNode*>(left);
    ExprIDNode* pRight = dynamic_cast<ExprIDNode*>(right);
    if (pLeft)
    {
        leftStr = pLeft->GetNodeCode();
    }
    if (pRight)
    {
        rightStr = pRight->GetNodeCode();
    }

    if (pLeft && pLeft->GetNodeType() != ExprType::ID && pLeft->GetNodeType() != ExprType::Expr && (leftStr.find(L"）") != std::wstring::npos || leftStr.find(L"（") != std::wstring::npos))
    {
        ParseError(EnErrorType::Undefine);
        return;
    }
    if (pRight && pRight->GetNodeType() != ExprType::ID && pRight->GetNodeType() != ExprType::Expr && (rightStr.find(L"）") != std::wstring::npos || rightStr.find(L"（") != std::wstring::npos))
    {
        ParseError(EnErrorType::Undefine);
        return;
    }

    // 单位运算+
    if (UnitHelper::CheckUnitAdd(left->GetUnitType(), right->GetUnitType(), result))
    {
        binarynode->m_data.SetUnitType(result);
    }
    else
    {
        if (pLeft && pLeft->GetNodeType() == ExprType::ID)
        {
            m_exprNodeName.emplace_back(pLeft->GetNodeCode());
        }
        if (pRight && pRight->GetNodeType() == ExprType::ID)
        {
            m_exprNodeName.emplace_back(pRight->GetNodeCode());
        }
        ParseError(EnErrorType::UnitInvalid);
        return;
    }
    // 数值运算
    if (left->GetDataType() == ExprDataType::Integer && right->GetDataType() == ExprDataType::Integer)
    {
        binarynode->m_data.SetType(ExprDataType::Integer);
        binarynode->m_data.SetAsInteger(left->GetData()->GetAsInteger() + right->GetData()->GetAsInteger());
    }
    else if (left->GetDataType() == ExprDataType::Integer && right->GetDataType() == ExprDataType::Float)
    {
        binarynode->m_data.SetType(ExprDataType::Float);
        binarynode->m_data.SetAsFloat(left->GetData()->GetAsInteger() + right->GetData()->GetAsFloat());
    }
    else if (left->GetDataType() == ExprDataType::Float && right->GetDataType() == ExprDataType::Integer)
    {
        binarynode->m_data.SetType(ExprDataType::Float);
        binarynode->m_data.SetAsFloat(left->GetData()->GetAsFloat() + right->GetData()->GetAsInteger());
    }
    else if (left->GetDataType() == ExprDataType::Float && right->GetDataType() == ExprDataType::Float)
    {
        binarynode->m_data.SetType(ExprDataType::Float);
        binarynode->m_data.SetAsFloat(left->GetData()->GetAsFloat() + right->GetData()->GetAsFloat());
    }
    else if (left->GetDataType() == ExprDataType::String && right->GetDataType() == ExprDataType::String) // 字符串相加
    {
        wstring str1 = left->GetData()->GetAsString();
        wstring str2 = right->GetData()->GetAsString();
        wstring str3 = str1 + str2;
        binarynode->m_data.SetType(ExprDataType::String);
        binarynode->m_data.SetAsString(str3.c_str());
    }
    else
        ParseError(EnErrorType::Undefine);
}

void ExprCustomParser::Evaluate()
{
    if (m_pEngine == nullptr)
        return;
    if (!m_isNull)
        EvaluateNode(m_opRootNode.get(), m_pEngine->GetNodeDataProvider());
}

const IExprEngine* ExprCustomParser::GetEngine() const
{
    return m_pEngine;
}

void ExprCustomParser::Match(ExprTokenType expected)
{
    if (m_currentToken == expected)
        m_currentToken = m_scanner.GetToken();
    else
        ParseError(EnErrorType::Undefine);
}

gcmp::OwnerPtr<ExprNode> ExprCustomParser::Expr()
{
    if (m_currentToken == ExprTokenType::EndInput)
    {
        ParseError(EnErrorType::RedundantRParen);
        Match(m_currentToken);
    }
    gcmp::OwnerPtr<ExprNode> t = State_Expr();
    while (m_currentToken == ExprTokenType::And || m_currentToken == ExprTokenType::Or)
    {
        gcmp::OwnerPtr<ExprCustumNode> p = NEW_AS_OWNER_PTR(ExprCustumNode);
        p->m_nodeType = ExprType::BinaryOperate;
        p->m_token = m_currentToken;
        p->m_opLeftChild = TransferOwnership(t);
        Match(m_currentToken);
        p->m_opRightChild = State_Expr();
        t = TransferOwnership(p);
    }
    return t;
}

gcmp::OwnerPtr<ExprNode> ExprCustomParser::State_Expr()
{
    gcmp::OwnerPtr<ExprNode> t = Simple_Expr();
    if (m_currentToken >= ExprTokenType::EQ && m_currentToken <= ExprTokenType::NotEQ)
    {
        gcmp::OwnerPtr<ExprCustumNode> p = NEW_AS_OWNER_PTR(ExprCustumNode);
        p->m_nodeType = ExprType::BinaryOperate;
        p->m_token = m_currentToken;
        p->m_opLeftChild = TransferOwnership(t);
        Match(m_currentToken);
        p->m_opRightChild = Simple_Expr();
        t = TransferOwnership(p);
    }
    return t;
}

gcmp::OwnerPtr<ExprNode> ExprCustomParser::Simple_Expr()
{
    gcmp::OwnerPtr<ExprNode> t = Term();
    while (m_currentToken == ExprTokenType::Plus || m_currentToken == ExprTokenType::Minus)
    {
        gcmp::OwnerPtr<ExprCustumNode> p = NEW_AS_OWNER_PTR(ExprCustumNode);
        p->m_nodeType = ExprType::BinaryOperate;
        p->m_token = m_currentToken;
        p->m_opLeftChild = TransferOwnership(t);
        Match(m_currentToken);
        p->m_opRightChild = Term();
        t = TransferOwnership(p);
    }
    return t;
}

gcmp::OwnerPtr<ExprNode> ExprCustomParser::Term()
{
    gcmp::OwnerPtr<ExprNode> t = Factor();
    if (m_currentToken == ExprTokenType::LParen)
    {
        // 某个数字或变量后是个左括号
        ParseError(EnErrorType::LParenAfterParam);
        Match(m_currentToken);
    }
    while (m_currentToken == ExprTokenType::Times || m_currentToken == ExprTokenType::Over || m_currentToken == ExprTokenType::Modulus)
    {
        gcmp::OwnerPtr<ExprCustumNode> p = NEW_AS_OWNER_PTR(ExprCustumNode);
        p->m_nodeType = ExprType::BinaryOperate;
        p->m_token = m_currentToken;
        p->m_opLeftChild = TransferOwnership(t);
        Match(m_currentToken);
        p->m_opRightChild = Factor();
        t = TransferOwnership(p);
    }
    return t;
}

// factor->[-](exp)|[-]number|[-]identifier|function(exp, exp, exp…)
gcmp::OwnerPtr<ExprNode> ExprCustomParser::Factor()
{
    gcmp::OwnerPtr<ExprCustumNode> t;
    gcmp::OwnerPtr<ExprCustumNode> p;
    if (m_currentToken == ExprTokenType::Minus || m_currentToken == ExprTokenType::Not)
    {
        FactorForUnaryOperate(t);
    }
    if (m_currentToken == ExprTokenType::Integer)
    {
        FactorForInt(p);
    }
    else if (m_currentToken == ExprTokenType::Float)
    {
        FactorForFloat(p);
    }
    else if (m_currentToken == ExprTokenType::String)
    {
        FactorForString(p);
    }
    else if (m_currentToken == ExprTokenType::True || m_currentToken == ExprTokenType::False)
    {
        FactorForBool(p);
    }
    else if (m_currentToken == ExprTokenType::ID)
    {
        FactorForID(p);
    }
    else if (m_currentToken == ExprTokenType::IDRef)
    {
        FactorForIDRef(p);
    }
    else if (m_currentToken == ExprTokenType::Function)
    {
        FactorForFunction(p);
    }
    else if (m_currentToken == ExprTokenType::ExprPaser)
    {
        // 嵌套的表达式解析变量，例如: 表达式为aa（aa = 2.0*bb + cc）
        gcmp::OwnerPtr<ExprIDNode> pParserID = NEW_AS_OWNER_PTR(ExprIDNode);
        pParserID->m_nodeType = ExprType::Expr;
        pParserID->m_token = m_currentToken;
        pParserID->m_startPosition = m_scanner.GetCurrentTokenStartPosition();
        pParserID->m_endPosition = m_scanner.GetCurrentTokenEndPosition();
        pParserID->SetNodeCode(m_scanner.GetTokenString());
        Match(m_currentToken);
        p = TransferOwnership(pParserID);
    }
    else if (m_currentToken == ExprTokenType::ExprPaserRef)
    {
        //嵌套的表达式解析变量，例如: 表达式为aa（aa = 2.0*bb + cc）
        gcmp::OwnerPtr<ExprIDNode> pParserID = NEW_AS_OWNER_PTR(ExprIDNode);
        pParserID->m_nodeType = ExprType::Expr;
        pParserID->m_token = m_currentToken;
        pParserID->m_startPosition = m_scanner.GetCurrentTokenStartPosition();
        pParserID->m_endPosition = m_scanner.GetCurrentTokenEndPosition();
        pParserID->SetNodeCode(m_scanner.GetRefIDTokenString().c_str());
        Match(m_currentToken);
        p = TransferOwnership(pParserID);
    }
    else if (m_currentToken == ExprTokenType::LParen)
    {
        Match(ExprTokenType::LParen);
        p = TransferOwnershipCast<ExprCustumNode>(Expr());
        Match(ExprTokenType::RParen);
    }
    else if (m_currentToken == ExprTokenType::RParen)
    {
        ParseError(EnErrorType::NullExprInParens);
        Match(m_currentToken);
    }
    else
    {
        ParseError(EnErrorType::LastBinary);
        Match(m_currentToken);
    }

    if (t)
        t->m_opLeftChild = TransferOwnership(p);
    else
        t = TransferOwnership(p);
    return TransferOwnership(t);
}

void ExprCustomParser::FactorForID(gcmp::OwnerPtr<ExprCustumNode>& p)
{
    gcmp::OwnerPtr<ExprIDNode> pID = NEW_AS_OWNER_PTR(ExprIDNode);
    pID->m_nodeType = ExprType::ID;
    pID->m_token = m_currentToken;
    pID->m_startPosition = m_scanner.GetCurrentTokenStartPosition();
    pID->m_endPosition = m_scanner.GetCurrentTokenEndPosition();
    pID->SetNodeCode(m_scanner.GetTokenString());
    Match(m_currentToken);
    p = TransferOwnership(pID);
}

void ExprCustomParser::FactorForIDRef(gcmp::OwnerPtr<ExprCustumNode>& p)
{
    gcmp::OwnerPtr<ExprIDNode> pID = NEW_AS_OWNER_PTR(ExprIDNode);
    pID->m_nodeType = ExprType::ID;
    pID->m_token = m_currentToken;
    pID->m_startPosition = m_scanner.GetCurrentTokenStartPosition();
    pID->m_endPosition = m_scanner.GetCurrentTokenEndPosition();
    pID->SetNodeCode(m_scanner.GetRefIDTokenString().c_str());
    Match(m_currentToken);
    p = TransferOwnership(pID);
}

void ExprCustomParser::FactorForUnaryOperate(gcmp::OwnerPtr<ExprCustumNode>& t)
{
    t = TransferOwnership(NEW_AS_OWNER_PTR(ExprCustumNode));
    t->m_nodeType = ExprType::UnaryOperate;
    t->m_token = m_currentToken;
    Match(m_currentToken);
}

void ExprCustomParser::FactorForBool(gcmp::OwnerPtr<ExprCustumNode>& p)
{
    p = TransferOwnership(NEW_AS_OWNER_PTR(ExprCustumNode));
    p->m_nodeType = ExprType::Const;
    p->m_token = m_currentToken;
    p->m_data.SetType(ExprDataType::Boolean);
    p->m_data.SetAsBoolean(m_currentToken == ExprTokenType::True);
    UnitMap type(ExprUnitType::Bool);
    p->m_data.SetUnitType(type);
    Match(m_currentToken);
}

void ExprCustomParser::FactorForString(gcmp::OwnerPtr<ExprCustumNode>& p)
{
    p = TransferOwnership(NEW_AS_OWNER_PTR(ExprCustumNode));
    p->m_nodeType = ExprType::Const;
    p->m_token = m_currentToken;
    p->m_data.SetType(ExprDataType::String);
    p->m_data.SetAsString(m_scanner.GetTokenString());
    Match(m_currentToken);
}

void ExprCustomParser::FactorForFloat(gcmp::OwnerPtr<ExprCustumNode>& p)
{
    p = TransferOwnership(NEW_AS_OWNER_PTR(ExprCustumNode));
    p->m_nodeType = ExprType::Const;
    p->m_token = m_currentToken;
    p->m_data.SetType(ExprDataType::Float);
    p->m_data.SetAsFloat(_wtof(m_scanner.GetTokenString()));
    UnitMap type(ExprUnitType::Num);
    p->m_data.SetUnitType(type);
    Match(m_currentToken);
}

void ExprCustomParser::FactorForInt(gcmp::OwnerPtr<ExprCustumNode>& p)
{
    p = TransferOwnership(NEW_AS_OWNER_PTR(ExprCustumNode));
    p->m_nodeType = ExprType::Const;
    p->m_token = m_currentToken;
    p->m_data.SetType(ExprDataType::Integer);
    p->m_data.SetAsInteger(_wtoi(m_scanner.GetTokenString()));
    UnitMap type(ExprUnitType::Num);
    p->m_data.SetUnitType(type);
    Match(m_currentToken);
}

void ExprCustomParser::FactorForFunction(gcmp::OwnerPtr<ExprCustumNode>& p)
{
    gcmp::OwnerPtr<ExprFunctionNode> pFunc = NEW_AS_OWNER_PTR(ExprFunctionNode);
    pFunc->m_nodeType = ExprType::Function;
    pFunc->m_token = m_currentToken;
    pFunc->SetNodeCode(m_scanner.GetTokenString());
    Match(m_currentToken);
    // 函数有可能有参数有可能没参数，有括号也有可能没参数
    if (m_currentToken == ExprTokenType::LParen)
    {
        Match(ExprTokenType::LParen);
        if (m_currentToken == ExprTokenType::RParen) // 有括号没参数的情况
            Match(ExprTokenType::RParen);
        else // 有括号有参数的情况
        {
            gcmp::OwnerPtr<ExprNode> pParam = Expr();
            pFunc->AppendParams(pParam);
            while (m_currentToken == ExprTokenType::Comma)
            {
                Match(ExprTokenType::Comma);
                pParam = Expr();
                pFunc->AppendParams(pParam);
            }
            Match(ExprTokenType::RParen);
        }
    }
    p = TransferOwnership(pFunc);
}

void ExprCustomParser::ParseError(EnErrorType errorType)
{
    m_isValid = false;
    m_errorPos = m_scanner.GetCurrentTokenStartPosition();
    m_errorType = errorType;
}

int ExprCustomParser::GetErrorPos() const
{
    return m_errorPos;
}


EnErrorType ExprCustomParser::GetErrorType() const
{
    return m_errorType;
}

namespace
{
    void VisitNode(const ExprNode* pNode, ExprNodeVisitor* pVisitor)
    {
        if (!pNode || !pVisitor)
            return;

        pVisitor->Visit(pNode);
        const ExprNode* left = (dynamic_cast<const ExprCustumNode*>(pNode))->m_opLeftChild.get();
        if (left)
        {
            VisitNode(left, pVisitor);
        }
        const ExprNode* right = (dynamic_cast<const ExprCustumNode*>(pNode))->m_opRightChild.get();
        if (right)
        {
            VisitNode(right, pVisitor);
        }
    }
}

void ExprCustomParser::Accept(ExprNodeVisitor* pVisitor) const
{
    if (!m_opRootNode)
        return;

    if (!m_isValid)
        return;

    if (!pVisitor)
        return;

    VisitNode(m_opRootNode.get(), pVisitor);
}

bool ExprCustomParser::IsCircularReferenced(const wchar_t* tokenName) const
{
    if (!tokenName || !m_pEngine || !m_opRootNode)
    {
        return false;
    }

    return FindToken(m_opRootNode.get(), tokenName);
}

bool ExprCustomParser::FindToken(const ExprNode* node, const wchar_t* tokenName) const
{
    if (!node || !tokenName)
    {
        return false;
    }

    if (node->GetNodeType() == ExprType::ID)
    {
        const ExprIDNode* pIDNode = dynamic_cast<const ExprIDNode*>(node);

        if (pIDNode && wcscmp(tokenName, pIDNode->GetNodeCode()) == 0)
        {
            return true;
        }
    }
    else if (node->GetNodeType() == ExprType::Expr)
    {
        const ExprIDNode* pExprNode = dynamic_cast<const ExprIDNode*> (node);

        if (pExprNode && wcscmp(tokenName, pExprNode->GetNodeCode()) == 0)
        {
            return true;
        }

        // 递归检查嵌套表达式
        if (pExprNode)
        {
            IExprParser* pCallParser = m_pEngine->FindParser(pExprNode->GetNodeCode());
            if (pCallParser)
            {
                return pCallParser->IsCircularReferenced(tokenName);
            }
        }
    }
    else if (node->GetNodeType() == ExprType::Function)
    {
        const ExprFunctionNode* pFuncNode = dynamic_cast<const ExprFunctionNode*>(node);
        if (pFuncNode && wcscmp(tokenName, pFuncNode->GetNodeCode()) == 0)
        {
            return true;
        }

        // 递归检查自定义函数
        if (pFuncNode)
        {
            int count = pFuncNode->GetParams()->Count();
            for (int i = 0; i < count; i++)
            {
                if (FindToken(pFuncNode->GetParams()->GetParamNode(i), tokenName))
                {
                    return true;
                }
            }
        }
    }

    const ExprNode* leftNode, * rightNode;
    leftNode = (dynamic_cast<const ExprCustumNode*>(node))->m_opLeftChild.get();
    rightNode = (dynamic_cast<const ExprCustumNode*>(node))->m_opRightChild.get();
    if (FindToken(leftNode, tokenName))
    {
        return true;
    }
    if (FindToken(rightNode, tokenName))
    {
        return true;
    }

    return false;
}

void ExprCustomParser::GetAllReferencedParamNames(std::set<const wchar_t*>& refParamNames) const
{
    if (!m_pEngine || !m_opRootNode)
        return;

    class RefParamNameVisitor : public ExprNodeVisitor
    {
    public:
        RefParamNameVisitor(std::set<const wchar_t*>& refParamNames) : m_refParamNames(refParamNames)
        {
        }
        void Visit(const ExprNode* pNode) override
        {
            if (!pNode)
                return;

            if (ExprType::Expr == pNode->GetNodeType() || ExprType::ID == pNode->GetNodeType())
            {
                ExprIDNode* pIDNode = (ExprIDNode*)pNode;
                m_refParamNames.insert(pIDNode->GetNodeCode());
            }
            else if (ExprType::Function == pNode->GetNodeType())
            {
                ExprFunctionNode* pFuncNode = (ExprFunctionNode*)pNode;
                // 递归查找自定义函数引用的参数名
                int count = pFuncNode->GetParams()->Count();
                for (int i = 0; i < count; i++)
                {
                    const CustomFunctionParams* pFunctionParams = pFuncNode->GetParams();
                    if (pFunctionParams && pFunctionParams->GetParamNode(i))
                    {
                        VisitNode(pFunctionParams->GetParamNode(i), this);
                    }
                }
            }
        }

    private:
        std::set<const wchar_t*>& m_refParamNames;
    };

    RefParamNameVisitor visitor(refParamNames);
    Accept(&visitor);
}

std::vector<const wchar_t*> ExprCustomParser::GetExprNodeNames() const
{
    return m_exprNodeName;
}

namespace
{
    void GetIDNodeRecursive(const wchar_t* nodeName, const ExprNode* node, std::vector<std::pair<int, int>>& result)
    {
        if (!nodeName || !node)
            return;

        switch (node->GetNodeType())
        {
        case ExprType::UnaryOperate:
        {
            const ExprNode* leftNode = (dynamic_cast<const ExprCustumNode*>(node))->m_opLeftChild.get();
            if (leftNode)
                GetIDNodeRecursive(nodeName, leftNode, result);
            break;
        }
        case ExprType::BinaryOperate:
        {
            const ExprNode* leftNode = (dynamic_cast<const ExprCustumNode*>(node))->m_opLeftChild.get();
            if (leftNode)
                GetIDNodeRecursive(nodeName, leftNode, result);

            const ExprNode* rightNode = (dynamic_cast<const ExprCustumNode*>(node))->m_opRightChild.get();
            if (rightNode)
                GetIDNodeRecursive(nodeName, rightNode, result);
            break;
        }
        case ExprType::Function:
        {
            const ExprFunctionNode* pFuncNode = dynamic_cast<const ExprFunctionNode*>(node);
            int paramCount = pFuncNode->GetParams()->Count();
            for (int i = 0; i < paramCount; i++)
            {
                const ExprNode* paramNode = pFuncNode->GetParams()->GetParamNode(i);
                if (paramNode)
                    GetIDNodeRecursive(nodeName, paramNode, result);
            }
            break;
        }
        case ExprType::ID:
        case ExprType::Expr:
        {
            const ExprIDNode* pIDNode = dynamic_cast<const ExprIDNode*>(node);
            if (pIDNode && 0 == wcscmp(nodeName, pIDNode->GetNodeCode()))
                result.push_back({ pIDNode->m_startPosition, pIDNode->m_endPosition });
            break;
        }
        }
    }
}

void ExprCustomParser::GetIDNodePositions(const std::wstring& nodeName, std::vector<std::pair<int, int>>& result) const
{
    GetIDNodeRecursive(nodeName.c_str(), m_opRootNode.get(), result);
    std::sort(result.begin(), result.end(), [](const std::pair<int, int>& i1, const std::pair<int, int>& i2) { return i1.first > i2.first; });
}
